/***************************************************************************
 *   Copyright (c) 2020 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/


#include "pch.h"


#include "Sketcher/App/GeometryFacade.h"

//#include "Base/Console.h" // Only for Debug, when/if necessary


using namespace Sketcher;

TYPESYSTEM_SOURCE(Sketcher::GeometryFacade, Base::BaseClass)

GeometryFacade::GeometryFacade(): Geo(nullptr), OwnerGeo(false) {}

GeometryFacade::GeometryFacade(const Part::Geometry* geometry, bool owner)
    : Geo(geometry), OwnerGeo(owner) {
    assert(geometry != nullptr); // This should never be nullptr, as this constructor is protected
    initExtension();
}

GeometryFacade::~GeometryFacade() {
    if (OwnerGeo && Geo != nullptr)
        delete Geo;
}

std::unique_ptr<GeometryFacade> GeometryFacade::getFacade(Part::Geometry* geometry, bool owner) {
    if(geometry != nullptr)
        return std::unique_ptr<GeometryFacade>(new GeometryFacade(geometry, owner));
    else
        return std::unique_ptr<GeometryFacade>(nullptr);
    //return std::make_unique<GeometryFacade>(geometry); // make_unique has no access to private constructor
}

std::unique_ptr<const GeometryFacade> GeometryFacade::getFacade(const Part::Geometry* geometry) {
    if(geometry != nullptr)
        return std::unique_ptr<const GeometryFacade>(new GeometryFacade(geometry));
    else
        return std::unique_ptr<const GeometryFacade>(nullptr);
    //return std::make_unique<const GeometryFacade>(geometry); // make_unique has no access to private constructor
}

void GeometryFacade::setGeometry(Part::Geometry* geometry) {
    Geo = geometry;

    if (geometry != nullptr)
        initExtension();
    else
        throw std::string("GeometryFacade initialized with Geometry null pointer");
}

void GeometryFacade::initExtension() {}

void GeometryFacade::initExtension() const {}

void GeometryFacade::throwOnNullPtr(const Part::Geometry* geo) {
    if (geo == nullptr)
        throw std::string("Geometry is nullptr!");
}

void GeometryFacade::ensureSketchGeometryExtension(Part::Geometry* geometry) {}

void GeometryFacade::copyId(const Part::Geometry* src, Part::Geometry* dst) {
    throwOnNullPtr(src);
    throwOnNullPtr(dst);

    auto gfsrc = getFacade(src);
    auto gfdst = getFacade(dst);
    gfdst->setId(gfsrc->getId());
}

bool GeometryFacade::getConstruction(const Part::Geometry* geometry) {
    throwOnNullPtr(geometry);

    auto gf = getFacade(geometry);
    return gf->getConstruction();
}

void GeometryFacade::setConstruction(Part::Geometry* geometry, bool construction) {
    throwOnNullPtr(geometry);

    auto gf = getFacade(geometry);
    return gf->setConstruction(construction);
}

bool GeometryFacade::isInternalType(const Part::Geometry* geometry, InternalType::InternalType type) {
    throwOnNullPtr(geometry);

    auto gf = getFacade(geometry);
    return gf->getInternalType() == type;
}

bool GeometryFacade::getBlocked(const Part::Geometry* geometry) {
    throwOnNullPtr(geometry);

    auto gf = getFacade(geometry);
    return gf->getBlocked();
}
